package llama.view.panels;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import llama.core.LoginSettings;
import llama.ctrl.ControllerFactory;
import llama.ctrl.EditHostCtrl;
import llama.ctrl.LoginClientCtrl;
import llama.ctrl.LoginSettingsCtrl;

import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;

public class LoginPanel extends JPanel {
	private JTextField txtEmail;
	private JPasswordField txtPassword;
	private JButton btnLoggaIn;
	private JLabel working;
	private JCheckBox chkRememberMe;
	
	private static final String EXAMPLE_TEXT = "example@email.se";
	private static final int ICON_TEXT_GAP = 5;
	private JCheckBox chkRememberPass;
	private JCheckBox chkAutoLogin;
	private JTextArea errorMessage;
	private String email = "";
	private LoginSettings settings;
	
	/**
	 * Create the panel.
	 */
	public LoginPanel() {
		setLayout(new FormLayout(new ColumnSpec[] {
				FormFactory.RELATED_GAP_COLSPEC,
				ColumnSpec.decode("default:grow"),
				FormFactory.RELATED_GAP_COLSPEC,},
			new RowSpec[] {
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,
				FormFactory.RELATED_GAP_ROWSPEC,
				FormFactory.DEFAULT_ROWSPEC,}));
		
		JLabel lblEmail = new JLabel("Email:");
		lblEmail.setFont(new Font("Tahoma", Font.PLAIN, 18));
		add(lblEmail, "2, 2");
		
		txtEmail = new JTextField();
		txtEmail.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				attemptLogin();
			}
		});
		txtEmail.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(java.awt.event.KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_F5) {
					String host = JOptionPane.showInputDialog("Host?");
					EditHostCtrl ctrl = (EditHostCtrl)ControllerFactory.getController(EditHostCtrl.class);
					ctrl.setHost(host);
					ctrl.execute();
				}
			};
		});
		txtEmail.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent arg0) {
				if(txtEmail.isEditable() &&
						txtEmail.getText().equals(EXAMPLE_TEXT)) {
					txtEmail.setForeground(Color.BLACK);
					txtEmail.setText("");
				}
			}
			@Override
			public void focusLost(FocusEvent e) {
				if(txtEmail.getText().equals("")) {
					txtEmail.setForeground(Color.GRAY);
					txtEmail.setText(EXAMPLE_TEXT);
				}
			}
		});
		txtEmail.setText(EXAMPLE_TEXT);
		txtEmail.setFont(new Font("Tahoma", Font.PLAIN, 14));
		add(txtEmail, "2, 4, fill, default");
		txtEmail.setColumns(10);
		
		JLabel lblLsenord = new JLabel("Password");
		lblLsenord.setFont(new Font("Tahoma", Font.PLAIN, 18));
		add(lblLsenord, "2, 6");
		
		txtPassword = new JPasswordField();
		txtPassword.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				attemptLogin();
			}
		});
		txtPassword.setFont(new Font("Tahoma", Font.PLAIN, 14));
		add(txtPassword, "2, 8, fill, default");
		
		working = new JLabel("Logging in...");
		working.setDoubleBuffered(true);
		working.setHorizontalTextPosition(SwingConstants.CENTER);
		working.setIconTextGap(ICON_TEXT_GAP);
		working.setVerticalTextPosition(SwingConstants.BOTTOM);
		working.setIcon(new ImageIcon("img/loading.gif"));
		add(working,"2, 24, center, default");
		
		chkRememberMe = new JCheckBox("Remember me");
		chkRememberMe.setIconTextGap(ICON_TEXT_GAP);
		chkRememberMe.setBorderPainted(false);
		add(chkRememberMe, "2, 14");
		
		chkRememberPass = new JCheckBox("Remember my password");
		chkRememberPass.setIconTextGap(ICON_TEXT_GAP);
		chkRememberPass.setBorderPainted(false);
		add(chkRememberPass, "2, 16");
		
		chkRememberMe.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				chkRememberPass.setSelected(false);
				chkRememberPass.setEnabled(chkRememberMe.isSelected());
				if (!chkRememberMe.isSelected()) {
					chkAutoLogin.setSelected(false);
					chkAutoLogin.setEnabled(false);
				}
			}
		});
		
		chkRememberPass.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				chkAutoLogin.setSelected(false);
				chkAutoLogin.setEnabled(chkRememberPass.isSelected());
			}
		});
		
		chkAutoLogin = new JCheckBox("Log me in automatically");
		chkAutoLogin.setIconTextGap(ICON_TEXT_GAP);
		chkAutoLogin.setBorderPainted(false);
		add(chkAutoLogin, "2, 18");
		
		btnLoggaIn = new JButton("Login");
		btnLoggaIn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				attemptLogin();
			}
		});
		btnLoggaIn.setFont(new Font("Tahoma", Font.PLAIN, 18));
		add(btnLoggaIn, "2, 10");
		
		errorMessage = new JTextArea("error message");
		errorMessage.setBackground(new Color(240, 240, 240));
		errorMessage.setWrapStyleWord(true);
		errorMessage.setLineWrap(true);
		errorMessage.setEditable(false);
		errorMessage.setForeground(Color.RED);
		errorMessage.setFont(new Font("Arial", Font.PLAIN, 14));
		add(errorMessage, "2, 22");

		initialVisuals();
	}
	
	public void loginFailed(String failMessage) {
		failedLoginVisuals(failMessage);
	}
	
	private void attemptLogin() {
		loginVisuals();
		email = txtEmail.getText();
		String password = new String(txtPassword.getPassword());
		
		login(email, password);
		
		// If remember checkboxes is selected or not
		String remEmail = null;
		String remPass = null;
		boolean remAutoLogin = false;
		if (chkRememberMe.isSelected()) {
			remEmail = email;
		}
		if (chkRememberPass.isSelected()) {
			remPass = password;
		}
		if (chkAutoLogin.isSelected()) {
			remAutoLogin = true;
		}
		
		this.settings = new LoginSettings(remEmail, remPass, remAutoLogin);
		
		LoginSettingsCtrl loginSettingsCtrl = (LoginSettingsCtrl)ControllerFactory.getController(LoginSettingsCtrl.class);
		loginSettingsCtrl.setSettings(remEmail, remPass, remAutoLogin);
		loginSettingsCtrl.execute();
	}
	
	private void initialVisuals() {
		txtEmail.setEditable(true);
		txtPassword.setEditable(true);
		btnLoggaIn.setEnabled(true);
		chkRememberMe.setEnabled(true);
		chkRememberPass.setEnabled(false);
		chkAutoLogin.setEnabled(false);
		
		chkRememberMe.setSelected(false);
		chkRememberPass.setSelected(false);
		chkAutoLogin.setSelected(false);
		
		txtEmail.setText(email);
		txtPassword.setText("");
		
		errorMessage.setVisible(false);
		working.setVisible(false);
		revalidate();
		repaint();
	}
	
	public void logoutVisuals() {
		initialVisuals();
		updateForm(false);
	}
	
	private void loginVisuals() {
		txtEmail.setEditable(false);
		txtPassword.setEditable(false);
		btnLoggaIn.setEnabled(false);
		chkRememberMe.setEnabled(false);
		chkRememberPass.setEnabled(false);
		chkAutoLogin.setEnabled(false);

		errorMessage.setVisible(false);
		working.setVisible(true);
		revalidate();
		repaint();
	}
	
	private void failedLoginVisuals(String failMessage) {
		initialVisuals();

		errorMessage.setText(failMessage);
		errorMessage.setVisible(true);
		revalidate();
		repaint();
	}
	
	public void updateLoginSettings(LoginSettings settings) {
		this.settings = settings;
		updateForm(true);
	}
	
	private void updateForm(boolean autoLogin){
		if (settings.getEmail() != null) {
			txtEmail.setText(settings.getEmail());
			chkRememberMe.setSelected(true);
			chkRememberPass.setEnabled(true);
			if (settings.getPassword() != null) {
				txtPassword.setText(settings.getPassword());
				chkRememberPass.setSelected(true);
				
				chkAutoLogin.setSelected(settings.getAutoLogin());
				chkAutoLogin.setEnabled(true);
			}
			else {
				chkAutoLogin.setEnabled(false);
			}
		}

		if (autoLogin && settings.getAutoLogin()) {
			login(settings.getEmail(), settings.getPassword());
		}
	}
	
	private void login(final String email, final String password) {
		LoginClientCtrl loginClient = (LoginClientCtrl)ControllerFactory.getController(LoginClientCtrl.class);
		loginClient.setLoginCredentials(email, password);
		loginClient.execute();
	}
	

}
